log要用占位符而不是用字符串拼接原因解析

您所在的位置:网站首页 loggerinfo日志没出来 slf4j log要用占位符而不是用字符串拼接原因解析

log要用占位符而不是用字符串拼接原因解析

#log要用占位符而不是用字符串拼接原因解析| 来源: 网络整理| 查看: 265

1.占位符是怎么用字符串替换的呢?

使用占位符的本质也是获取每个参数,找到位置通过StringBuilder拼接。

所以不能说字符串拼接的方式使用了StringBuilder的append()有一定的性能损耗。使用占位符仅是替换动作,效率更高。

可以参考这篇文章的源码截图(关于Slf4j中占位符{}_Firm陈的博客-CSDN博客)

2.那为什么还要使用占位符呢?

参考这篇文章(日志使用占位符还是直接拼接 - 简书)

占位符和直接拼接的性能比较

通过main方法for循环测试占位符和直接拼接10w次以后的用时,发现直接拼接的耗时较短;那么这样可以得到一个简单的结论,拼接耗时短,性能表面上看要比占位符性能高。 既然这样的话,我们为什么不直接使用拼接,反而越来越多的框架选择使用了占位符。

从实际出发

一般项目里面有很多debug级别的日志,可以帮助我们快速定位线上问题,提交生产解决问题的效率,但是一般线上的日志级别会比较高,debug是不会打印的,这个时候就出现了一个问题,使用拼接方式的时候会进行内存空间的开辟,stringbuilder进行拼接,但是进入日志断点后,发现并不需要进行日志打印,这部分的开销就变的没有意义,而使用占位符的时候,只有需要打印的时候才会进行拼接,减少了内存的开销,性能得到了提升。

 3.使用占位符后为什么需要打印日志的时候才会进行拼接?

参考这篇文章(为什么说log用占位符比用字符串连接比较好 - 我欲皆真 - 博客园)

如果在日志等级符合输出条件的情况下,两个是没有什么大区别的。

但如果是在日志等级不符合输出条件的情况下:

由于字符串拼接是作为一个方法参数的,意味着它进入logback的内部判断的时候,就已经是拼接成功了。而在这一步的拼接成功,涉及到String是一个final变量的问题,这个拼接是耗时了,创建了String,但是进入判断之后又完全没什么用。

这两种是有区别的:

log.info("a" + "b");    // 没有影响,因为在编译时已经是常量了,一共1个变量

log.info(a + "b"); // 有影响,a变量是1个,常量"b"是一个,拼接后的有事一个,一共三个变量。

而如果是占位符的话,它直接在logback的内部判断了日志等级是否足以输出,不行就直接return了。

4.slf4j与log4j

参考这篇文章(LOG使用规范(整理) - 简书)

日志工具的选择 推荐使用SLF4J(Simple Logging Facade for Java)作为日志的api,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。与使用apache commons-logging和直接使用log4j相比,SLF4J提供了一个名为参数化日志的高级特性,可以显著提高在配置为关闭日志的情况下的日志语句性能

//slf4j log.debug("Found {} records matching filter: '{}'", records, filter); //log4j log.debug("Found " + records + " records matching filter: '" + filter + "'");

可以看出SLF4J的方式一方面更简略易读,另一方面少了字符串拼接的开销,并且在日志级别达不到时(这里例子即为设置级别为debug以上),不会调用对象的toString方法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3